﻿using System.Security.Cryptography;
using System.Text;

namespace OnWork.Admin.Util.Base
{
    public class RSACryption
    {
        //
        // 摘要:
        //     RSA产生密钥
        //
        // 参数:
        //   xmlKeys:
        //     私钥
        //
        //   xmlPublicKey:
        //     公钥
        public void RSAKey(out string xmlKeys, out string xmlPublicKey)
        {
            try
            {
                RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
                xmlKeys = rSACryptoServiceProvider.ToXmlString(includePrivateParameters: true);
                xmlPublicKey = rSACryptoServiceProvider.ToXmlString(includePrivateParameters: false);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     RSA的加密函数
        //
        // 参数:
        //   xmlPublicKey:
        //     公钥
        //
        //   encryptString:
        //     待加密的字符串
        public string RSAEncrypt(string xmlPublicKey, string encryptString)
        {
            try
            {
                RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
                rSACryptoServiceProvider.FromXmlString(xmlPublicKey);
                byte[] bytes = new UnicodeEncoding().GetBytes(encryptString);
                byte[] inArray = rSACryptoServiceProvider.Encrypt(bytes, fOAEP: false);
                return Convert.ToBase64String(inArray);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     RSA的加密函数
        //
        // 参数:
        //   xmlPublicKey:
        //     公钥
        //
        //   EncryptString:
        //     待加密的字节数组
        public string RSAEncrypt(string xmlPublicKey, byte[] EncryptString)
        {
            try
            {
                RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
                rSACryptoServiceProvider.FromXmlString(xmlPublicKey);
                byte[] inArray = rSACryptoServiceProvider.Encrypt(EncryptString, fOAEP: false);
                return Convert.ToBase64String(inArray);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     RSA的解密函数
        //
        // 参数:
        //   xmlPrivateKey:
        //     私钥
        //
        //   decryptString:
        //     待解密的字符串
        public string RSADecrypt(string xmlPrivateKey, string decryptString)
        {
            try
            {
                RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
                rSACryptoServiceProvider.FromXmlString(xmlPrivateKey);
                byte[] rgb = Convert.FromBase64String(decryptString);
                byte[] bytes = rSACryptoServiceProvider.Decrypt(rgb, fOAEP: false);
                return new UnicodeEncoding().GetString(bytes);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     RSA的解密函数
        //
        // 参数:
        //   xmlPrivateKey:
        //     私钥
        //
        //   DecryptString:
        //     待解密的字节数组
        public string RSADecrypt(string xmlPrivateKey, byte[] DecryptString)
        {
            try
            {
                RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
                rSACryptoServiceProvider.FromXmlString(xmlPrivateKey);
                byte[] bytes = rSACryptoServiceProvider.Decrypt(DecryptString, fOAEP: false);
                return new UnicodeEncoding().GetString(bytes);
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     获取Hash描述表
        //
        // 参数:
        //   strSource:
        //     待签名的字符串
        //
        //   HashData:
        //     Hash描述
        public bool GetHash(string strSource, ref byte[] HashData)
        {
            try
            {
                HashAlgorithm hashAlgorithm = HashAlgorithm.Create("MD5");
                byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(strSource);
                HashData = hashAlgorithm.ComputeHash(bytes);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     获取Hash描述表
        //
        // 参数:
        //   strSource:
        //     待签名的字符串
        //
        //   strHashData:
        //     Hash描述
        public bool GetHash(string strSource, ref string strHashData)
        {
            try
            {
                HashAlgorithm hashAlgorithm = HashAlgorithm.Create("MD5");
                byte[] bytes = Encoding.GetEncoding("GB2312").GetBytes(strSource);
                byte[] inArray = hashAlgorithm.ComputeHash(bytes);
                strHashData = Convert.ToBase64String(inArray);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     获取Hash描述表
        //
        // 参数:
        //   objFile:
        //     待签名的文件
        //
        //   HashData:
        //     Hash描述
        public bool GetHash(FileStream objFile, ref byte[] HashData)
        {
            try
            {
                HashAlgorithm hashAlgorithm = HashAlgorithm.Create("MD5");
                HashData = hashAlgorithm.ComputeHash(objFile);
                objFile.Close();
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     获取Hash描述表
        //
        // 参数:
        //   objFile:
        //     待签名的文件
        //
        //   strHashData:
        //     Hash描述
        public bool GetHash(FileStream objFile, ref string strHashData)
        {
            try
            {
                HashAlgorithm hashAlgorithm = HashAlgorithm.Create("MD5");
                byte[] inArray = hashAlgorithm.ComputeHash(objFile);
                objFile.Close();
                strHashData = Convert.ToBase64String(inArray);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     RSA签名
        //
        // 参数:
        //   strKeyPrivate:
        //     私钥
        //
        //   HashbyteSignature:
        //     待签名Hash描述
        //
        //   EncryptedSignatureData:
        //     签名后的结果
        public bool SignatureFormatter(string strKeyPrivate, byte[] HashbyteSignature, ref byte[] EncryptedSignatureData)
        {
            try
            {
                RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
                rSACryptoServiceProvider.FromXmlString(strKeyPrivate);
                RSAPKCS1SignatureFormatter rSAPKCS1SignatureFormatter = new RSAPKCS1SignatureFormatter(rSACryptoServiceProvider);
                rSAPKCS1SignatureFormatter.SetHashAlgorithm("MD5");
                EncryptedSignatureData = rSAPKCS1SignatureFormatter.CreateSignature(HashbyteSignature);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     RSA签名
        //
        // 参数:
        //   strKeyPrivate:
        //     私钥
        //
        //   HashbyteSignature:
        //     待签名Hash描述
        //
        //   m_strEncryptedSignatureData:
        //     签名后的结果
        public bool SignatureFormatter(string strKeyPrivate, byte[] HashbyteSignature, ref string strEncryptedSignatureData)
        {
            try
            {
                RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
                rSACryptoServiceProvider.FromXmlString(strKeyPrivate);
                RSAPKCS1SignatureFormatter rSAPKCS1SignatureFormatter = new RSAPKCS1SignatureFormatter(rSACryptoServiceProvider);
                rSAPKCS1SignatureFormatter.SetHashAlgorithm("MD5");
                byte[] inArray = rSAPKCS1SignatureFormatter.CreateSignature(HashbyteSignature);
                strEncryptedSignatureData = Convert.ToBase64String(inArray);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     RSA签名
        //
        // 参数:
        //   strKeyPrivate:
        //     私钥
        //
        //   strHashbyteSignature:
        //     待签名Hash描述
        //
        //   EncryptedSignatureData:
        //     签名后的结果
        public bool SignatureFormatter(string strKeyPrivate, string strHashbyteSignature, ref byte[] EncryptedSignatureData)
        {
            try
            {
                byte[] rgbHash = Convert.FromBase64String(strHashbyteSignature);
                RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
                rSACryptoServiceProvider.FromXmlString(strKeyPrivate);
                RSAPKCS1SignatureFormatter rSAPKCS1SignatureFormatter = new RSAPKCS1SignatureFormatter(rSACryptoServiceProvider);
                rSAPKCS1SignatureFormatter.SetHashAlgorithm("MD5");
                EncryptedSignatureData = rSAPKCS1SignatureFormatter.CreateSignature(rgbHash);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     RSA签名
        //
        // 参数:
        //   strKeyPrivate:
        //     私钥
        //
        //   strHashbyteSignature:
        //     待签名Hash描述
        //
        //   strEncryptedSignatureData:
        //     签名后的结果
        public bool SignatureFormatter(string strKeyPrivate, string strHashbyteSignature, ref string strEncryptedSignatureData)
        {
            try
            {
                byte[] rgbHash = Convert.FromBase64String(strHashbyteSignature);
                RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
                rSACryptoServiceProvider.FromXmlString(strKeyPrivate);
                RSAPKCS1SignatureFormatter rSAPKCS1SignatureFormatter = new RSAPKCS1SignatureFormatter(rSACryptoServiceProvider);
                rSAPKCS1SignatureFormatter.SetHashAlgorithm("MD5");
                byte[] inArray = rSAPKCS1SignatureFormatter.CreateSignature(rgbHash);
                strEncryptedSignatureData = Convert.ToBase64String(inArray);
                return true;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     RSA签名验证
        //
        // 参数:
        //   strKeyPublic:
        //     公钥
        //
        //   HashbyteDeformatter:
        //     Hash描述
        //
        //   DeformatterData:
        //     签名后的结果
        public bool SignatureDeformatter(string strKeyPublic, byte[] HashbyteDeformatter, byte[] DeformatterData)
        {
            try
            {
                RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
                rSACryptoServiceProvider.FromXmlString(strKeyPublic);
                RSAPKCS1SignatureDeformatter rSAPKCS1SignatureDeformatter = new RSAPKCS1SignatureDeformatter(rSACryptoServiceProvider);
                rSAPKCS1SignatureDeformatter.SetHashAlgorithm("MD5");
                if (rSAPKCS1SignatureDeformatter.VerifySignature(HashbyteDeformatter, DeformatterData))
                {
                    return true;
                }

                return false;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     RSA签名验证
        //
        // 参数:
        //   strKeyPublic:
        //     公钥
        //
        //   strHashbyteDeformatter:
        //     Hash描述
        //
        //   DeformatterData:
        //     签名后的结果
        public bool SignatureDeformatter(string strKeyPublic, string strHashbyteDeformatter, byte[] DeformatterData)
        {
            try
            {
                byte[] rgbHash = Convert.FromBase64String(strHashbyteDeformatter);
                RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
                rSACryptoServiceProvider.FromXmlString(strKeyPublic);
                RSAPKCS1SignatureDeformatter rSAPKCS1SignatureDeformatter = new RSAPKCS1SignatureDeformatter(rSACryptoServiceProvider);
                rSAPKCS1SignatureDeformatter.SetHashAlgorithm("MD5");
                if (rSAPKCS1SignatureDeformatter.VerifySignature(rgbHash, DeformatterData))
                {
                    return true;
                }

                return false;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     RSA签名验证
        //
        // 参数:
        //   strKeyPublic:
        //     公钥
        //
        //   HashbyteDeformatter:
        //     Hash描述
        //
        //   strDeformatterData:
        //     签名后的结果
        public bool SignatureDeformatter(string strKeyPublic, byte[] HashbyteDeformatter, string strDeformatterData)
        {
            try
            {
                RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
                rSACryptoServiceProvider.FromXmlString(strKeyPublic);
                RSAPKCS1SignatureDeformatter rSAPKCS1SignatureDeformatter = new RSAPKCS1SignatureDeformatter(rSACryptoServiceProvider);
                rSAPKCS1SignatureDeformatter.SetHashAlgorithm("MD5");
                byte[] rgbSignature = Convert.FromBase64String(strDeformatterData);
                if (rSAPKCS1SignatureDeformatter.VerifySignature(HashbyteDeformatter, rgbSignature))
                {
                    return true;
                }

                return false;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        //
        // 摘要:
        //     RSA签名验证
        //
        // 参数:
        //   strKeyPublic:
        //     公钥
        //
        //   strHashbyteDeformatter:
        //     Hash描述
        //
        //   strDeformatterData:
        //     签名后的结果
        public bool SignatureDeformatter(string strKeyPublic, string strHashbyteDeformatter, string strDeformatterData)
        {
            try
            {
                byte[] rgbHash = Convert.FromBase64String(strHashbyteDeformatter);
                RSACryptoServiceProvider rSACryptoServiceProvider = new RSACryptoServiceProvider();
                rSACryptoServiceProvider.FromXmlString(strKeyPublic);
                RSAPKCS1SignatureDeformatter rSAPKCS1SignatureDeformatter = new RSAPKCS1SignatureDeformatter(rSACryptoServiceProvider);
                rSAPKCS1SignatureDeformatter.SetHashAlgorithm("MD5");
                byte[] rgbSignature = Convert.FromBase64String(strDeformatterData);
                if (rSAPKCS1SignatureDeformatter.VerifySignature(rgbHash, rgbSignature))
                {
                    return true;
                }

                return false;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
    }

    public static class JWT
    {
        private static readonly string privatekey = "<RSAKeyValue><Modulus>rZf79Tm8GR0VN+WGYcPWDMhxti36KCEGa/S0fBoxHP0HE7y/smKkXsjWottQC9t7FC/06X/YE3MPlmfY/LuyUQ/Nvl3zkDMMwt1yuzotjHBOgEFsCygYU9982GMu1nGukJIAPMqvQE0kLv8CekKB6rPSLDz7DDrnEtRaQWz4Rc0=</Modulus><Exponent>AQAB</Exponent><P>zReSn7bPbeT5yEPGeS4pEp8iJfbvxdJJCHAFQqHWnAzQaIPofa+QfKqn8U9f+qemK9DmdxDrbUtExw4Qo2wf4w==</P><Q>2K7edco5DuVsXcsvBipaU6CfYFaakMQficcQ2nYFy01INF20mX008xUOelGzW/D3Pr5ODWB8Hzk9DDmceIGSjw==</Q><DP>jWvO0FEXsditoLmTd2YsLkoLGxCu/8LkV2wfRHYibVKstxUWUOyp/j0TN2ObdFT8UcRn1vyUyrWXRIdfU8EwLw==</DP><DQ>wFUX6X4Cf5JtSiPcLaDSZICidyToNa+gPu+PqhowsnB6suCqOcPFiC8clr6GcgnFrM/HAGCwTBbGdV994AlDSQ==</DQ><InverseQ>I8KNrAEzrCqaHI+IzD72JJSIo6e4LVhdFuBgbT6bPgO3SazsDT83ZMXthBrSSQP07lI/1YaAQuNGM8hhYvSINg==</InverseQ><D>XEEyUN/O/BW9qggcA6b9Aawg6m3CzULH0+WnaXDN+xbphO7Bfb74lbrsfn5JKxQIc/EMmm8r2SJD/W3RHndtytCRctv2qfMNj5KSvomNIBGtRmXRTyqIfhGB6j4vhdCplVq6XKscw8kW1RGWKQlk4oL1yQrUc6WNknxccGAlW60=</D></RSAKeyValue>";

        private static readonly string publickey = "<RSAKeyValue><Modulus>rZf79Tm8GR0VN+WGYcPWDMhxti36KCEGa/S0fBoxHP0HE7y/smKkXsjWottQC9t7FC/06X/YE3MPlmfY/LuyUQ/Nvl3zkDMMwt1yuzotjHBOgEFsCygYU9982GMu1nGukJIAPMqvQE0kLv8CekKB6rPSLDz7DDrnEtRaQWz4Rc0=</Modulus><Exponent>AQAB</Exponent></RSAKeyValue>";

        //
        // 摘要:
        //     获取Token
        //
        // 参数:
        //   id:
        //     唯一ID，用于数据权限储存关联
        //
        //   userid:
        //     用户ID
        //
        //   ip:
        //     授权IP
        //
        //   exp:
        //     有效日期
        public static string GetToken(string id, string ip)
        {
            RSACryption rSACryption = new RSACryption();
            return Convert.ToBase64String(Encoding.Default.GetBytes(rSACryption.RSAEncrypt(publickey, id + "#" + ip)));
        }

        //
        // 摘要:
        //     增加有效期
        //
        // 参数:
        //   id:
        //
        //   ip:
        public static string GetTokenByDate(string id)
        {
            RSACryption rSACryption = new RSACryption();
            return Convert.ToBase64String(Encoding.Default.GetBytes(rSACryption.RSAEncrypt(publickey, id + "#" + DateTime.Now.AddMinutes(5.0).ToString())));
        }

        /// <summary>
        /// 获取token
        /// </summary>
        /// <param name="id"></param>
        /// <param name="days"></param>
        /// <returns></returns>
        public static string GetTokenByDate(string id, int days)
        {
            RSACryption rSACryption = new RSACryption();
            return Convert.ToBase64String(Encoding.Default.GetBytes(rSACryption.RSAEncrypt(publickey, id + "#" + DateTime.Now.AddDays(days).ToString())));
        }

        public static bool CheckTokenByDate(string token, out JWT_TokenUser user)
        {
            user = null;
            RSACryption rSACryption = new RSACryption();
            try
            {
                string[] array = rSACryption.RSADecrypt(privatekey, Encoding.Default.GetString(Convert.FromBase64String(token))).Split('#');
                if (array.Length != 2)
                {
                    return false;
                }

                user = new JWT_TokenUser
                {
                    id = array[0],
                    dt = array[1]
                };
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }

        //
        // 摘要:
        //     验证token是否有限返回验证的用户信息
        //
        // 参数:
        //   token:
        //     待验证的token
        //
        //   ip:
        //     验证ip
        //
        //   user:
        //     返回用户
        public static bool CheckToken(string token, string ip, out JWT_TokenUser user)
        {
            user = null;
            RSACryption rSACryption = new RSACryption();
            try
            {
                string[] array = rSACryption.RSADecrypt(privatekey, Encoding.Default.GetString(Convert.FromBase64String(token))).Split('#');
                if (array.Length != 2)
                {
                    return false;
                }

                user = new JWT_TokenUser
                {
                    id = array[0],
                    dt = array[1]
                };
                return true;
            }
            catch (Exception)
            {
                return false;
            }
        }
    }

    public class JWT_TokenUser
    {
        /// <summary>
        /// userID
        /// </summary>
        public string id
        {
            get;
            set;
        }

        /// <summary>
        /// 日期
        /// </summary>
        public string dt
        {
            get;
            set;
        }
    }
}